import { type FC, type Key, useMemo } from 'react';
import { View, TouchableWithoutFeedback } from 'react-native';
import { useSafeState, useMemoizedFn, useUpdateEffect } from 'ahooks';
import { AntDesign } from '@expo/vector-icons';
import DropdownConfirm from '../DropdownConfirm';
import type { SelectProps } from './types';
import type { MenuItemType } from '../Menu/types';
import Input from '../Input';
import Menu from '../Menu';
import styles from './styles';

const Select: FC<SelectProps> = (props) => {
  const {
    value,
    items = [],
    valueEnum = {},
    multiple = false,
    placeholder = 'Please select'
  } = props;

  const [show, setShow] = useSafeState(false);
  const [active, setActive] = useSafeState(false);

  const getArrValue = useMemoizedFn(() => {
    if (!value) return [];
    return Array.isArray(value) ? value : [value];
  });

  const [
    activeKeys,
    setActiveKeys
  ] = useSafeState<Key[]>(getArrValue());

  let [
    menuKeys,
    setMenuKeys
  ] = useSafeState<Key[]>(activeKeys);

  const menuItems = useMemo(() => {
    if (items.length > 0) return items;
    const keys = Object.keys(valueEnum);
    return keys.map<MenuItemType>(key => {
      const label = valueEnum[key];
      return { label, value: key };
    });
  }, [items, valueEnum]);

  const showLabel = useMemo(() => {
    return activeKeys.map(key => {
      return menuItems.find(item => item.value === key);
    }).map(item => item?.label).filter(v => v).join(',');
  }, [activeKeys, menuItems]);

  const updateState = useMemoizedFn(() => {
    const arr = getArrValue();
    const val1 = arr.join('');
    const val2 = activeKeys.join('');
    if (val1 !== val2) setActiveKeys(arr);
  });

  const onPressIn = useMemoizedFn(() => {
    setActive(true);
  });

  const onPressOut = useMemoizedFn(() => {
    setActive(false);
  });

  const closePicker = useMemoizedFn(() => {
    setShow(false);
  });

  const openPicker = useMemoizedFn(() => {
    setShow(true);
  });

  const onConfirm = useMemoizedFn(() => {
    closePicker();
    props.onChnage?.(menuKeys);
    if (!value) setActiveKeys(menuKeys);
  });

  const afterClose = useMemoizedFn(() => {
    setMenuKeys(activeKeys);
  });

  const onMenuChange = useMemoizedFn((key: Key) => {
    let update = false;
    const index = menuKeys.findIndex(v => key === v);
    // 多选
    if (multiple) {
      if (index > -1) {
        if (menuKeys.length > 1) {
          update = true;
          menuKeys.splice(index, 1);
        }
      } else {
        update = true;
        menuKeys.push(key);
      }
    } else {
      if (index < 0) {
        update = true;
        menuKeys = [key];
      }
    }
    if (update) {
      setMenuKeys([...menuKeys]);
    }
  });

  useUpdateEffect(updateState, [value]);

  return (
    <View style={styles.container}>
      <Input
        readOnly
        active={active}
        value={showLabel}
        prefix={props.prefix}
        placeholder={placeholder}
        suffix={() => {
          return (
            <AntDesign
              name="down"
              size={16}
              color="#666"
            />
          )
        }}
      />
      <TouchableWithoutFeedback
        disabled={props.disabled}
        onPress={openPicker}
        onPressIn={onPressIn}
        onPressOut={onPressOut}
      >
        <View style={styles.btn} />
      </TouchableWithoutFeedback>
      <DropdownConfirm
        open={show}
        okText="Done"
        destroyOnClose
        onOk={onConfirm}
        onClose={closePicker}
        afterClose={afterClose}
      >
        {() => (
          <Menu
            items={menuItems}
            activeKeys={menuKeys}
            onChange={onMenuChange}
          />
        )}
      </DropdownConfirm>
    </View>
  );
}

export default Select;